package com.bigcat.gulimall.gulimallsearch.thread;

import java.util.concurrent.*;

/**
 * 线程池测试
 *
 * @author sufer
 * @since 2021/7/21
 */
public class ThreadTest {
    /**
     * * @param corePoolSize the number of threads to keep in the pool, even
     * *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * * @param maximumPoolSize the maximum number of threads to allow in the
     * *        pool
     * * @param keepAliveTime when the number of threads is greater than
     * *        the core, this is the maximum time that excess idle threads
     * *        will wait for new tasks before terminating.
     * * @param unit the time unit for the {@code keepAliveTime} argument
     * * @param workQueue the queue to use for holding tasks before they are
     * *        executed.  This queue will hold only the {@code Runnable}
     * *        tasks submitted by the {@code execute} method.
     * * @param threadFactory the factory to use when the executor
     * *        creates a new thread
     * * @param handler the handler to use when execution is blocked
     * *        because the thread bounds and queue capacities are reached
     */
    public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            20,
            100,
            20,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100000),//默认容量是integer的最大值，这样会导致内存溢出，可以根据压测测出系统最大承受数量进行设置
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());//采用默认的拒绝策略：直接丢弃
    //几种常见的线程池
    //固定线程池，max和care都是一样的
    public static ExecutorService executorService = Executors.newFixedThreadPool(10);
//    //缓存线程池，核心线程为零，所以创建的线程都可以被回收
//    public static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//    //定时任务线程池
//    public static ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(100);
//    //单线程池、后台从队列里获取任务，挨个执行
//    public static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();


    public static void main(String[] args) throws Exception {
        System.out.println("start----------------------");
        //runAsync   启动线程，如果未指定线程池，使用的是默认的线程池，如果指定了线程池，那就使用我们自己的线程池
//        CompletableFuture.runAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 2;
//            System.out.println("运行结果：" + i);
//        }, executorService);


        //supplyAsync CompletableFuture集成了Future，可以使用get()来获得返回值
//        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 0;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executorService).whenComplete((result, exception) -> {//result:结果，exception：异常
//            //虽然whenComplete可以感知异常，但是无法修改返回值
//            System.out.println("执行异步完成回调方法------结果是：" + result + "异常是：" + exception);
//        }).exceptionally(throwable -> {
//            //exceptionally可感知异常，也可返回默认值
//            System.out.println("出现异常回调执行------");
//            return 10;
//        });

        //handle()方法完成处理
//        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 0;
//            System.out.println("运行结果：" + i);
//            return i;
//            //方法完成后的处理
//        }, executorService).handle((result, exception) -> {//可以获得结果、感知异常、也可以返回处理结果
//            System.out.println("方法完成后的处理------");
//            if(null != result){
//                return result * 10;
//            }
//            if (null != exception){
//                return 2;
//            }
//            return 1;
//        });

        //thenRunAsync()任务1方法执行完后执行任务2，不能获取上一步的执行结果，没有异常感知
//        CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {//任务1
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 4;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executorService).thenRunAsync(() -> {//任务1方法执行完后执行任务2，不能获取上一步的执行结果，没有异常感知
//            System.out.println("任务2启动----------");
//        }, executorService);


//        thenAcceptAsync()//可接收上一步的执行结果，没有返回值
//        CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {//任务1
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 4;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executorService).thenAcceptAsync((result) -> {//可接收上一步的执行结果，没有返回值
//            System.out.println("任务2启动----------:"+result);
//        }, executorService);

        //thenApplyAsync()可接收上一步的执行结果，有返回值
//        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {//任务1
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 100 / 4;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executorService).thenApplyAsync((result) -> {//可接收上一步的执行结果，有返回值
//            System.out.println("任务2启动----------:" + result);
//            //有返回值
//            return result * 2;
//        }, executorService);
        //任务1
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1执行-------------");
            int i = 100 / 4;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1运行结果：" + i);
            return i;
        }, executorService);

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2执行-------------");
            return 2;
        }, executorService);

        //不可接收任务执行结果，无返回值，
//        CompletableFuture<Void> future3 = future1.runAfterBothAsync(future2, () -> {
//            System.out.println("任务3执行-------------------");
//        }, executorService);

        //可接收任务执行结果，无返回值，
//        CompletableFuture<Void> future3 = future1.thenAcceptBothAsync(future2, (result1, result2) -> {
//            System.out.println("任务3执行-------------------result1:" + result1 + "   result2:" + result2);
//        }, executorService);

        //可接收任务执行结果，有返回值，
//        CompletableFuture<String> future3 = future1.thenCombineAsync(future2, (result1, result2) -> {
//            System.out.println("任务3执行-------------------result1:" + result1 + "   result2:" + result2);
//
//            return result1 + result2;
//        }, executorService);

        //runAfterEitherAsync()，两个任务完成一个即可，不可接收任务执行结果，无返回值
//        future1.runAfterEitherAsync(future2, () -> {
//            System.out.println("任务三执行，其中一个任务完成");
//        }, executorService);
        //acceptEitherAsync(),两个任务完成一个即可，可接受任务执行结果，无返回值
//        future1.acceptEitherAsync(future2,(result)->{
//            System.out.println("任务三执行，其中一个任务完成:"+result);
//        },executorService);

        //acceptEitherAsync(),两个任务完成一个即可，可接受任务执行结果，无返回值
        CompletableFuture<Integer> future3 = future1.applyToEitherAsync(future2, (result) -> {
            System.out.println("任务三执行，其中一个任务完成:" + result);
            return result;
        }, executorService);
//        //获得最终返回结果
        Integer result = future3.get();
        System.out.println("返回值:" + result);

        System.out.println("end----------------------");
    }
}
